package edu.yngsxy.wkstudy.Interceptor;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.yngsxy.wkstudy.core.model.common.Result;
import jakarta.annotation.Resource;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Set;

@RestControllerAdvice
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {
    // 使用不可变集合存储排除路径（Java 9+ 特性）
    private static final Set<String> EXCLUDED_PATHS = Set.of("/v3/api-docs", "/swagger-ui", "/swagger-resources");
    @Resource
    private ObjectMapper objectMapper;  // 注入Jackson的对象映射器
    /**
     * 判断是否需要对响应进行处理（返回true则进入beforeBodyWrite方法）
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 过排除已手动封装为Result的情况（避免重复封装）
        if (returnType.getParameterType().isAssignableFrom(Result.class)) {
            return false;
        }
        // 排除Swagger相关接口（避免文档页面响应格式异常）
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            return false;  // 非Web请求场景不处理
        }
        // 获取当前请求路径
        String requestPath = requestAttributes.getRequest().getRequestURI();
        // 使用Stream API判断是否包含任何排除路径（noneMatch表示"没有匹配项时返回true"）
        return EXCLUDED_PATHS.stream().noneMatch(requestPath::contains);
    }

    /**
     * 对响应体进行处理（封装为统一格式）
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        // 统一封装为成功响应
        Result<Object> result = Result.success(body);
        // 处理String类型的特殊情况（避免JSON转换异常）
        if (body instanceof String) {
            try {
                return objectMapper.writeValueAsString(result);
            } catch (JsonProcessingException e) {
                throw new RuntimeException("String类型响应转换失败", e);
            }
        }

        return result;
    }
}